package com.ideal.manage.esms.service.monitor;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ideal.manage.esms.bean.DTO.EquipmentStatus;
import com.ideal.manage.esms.bean.diagnostic.DiagnoseResultInfo;
import com.ideal.manage.esms.bean.esms.EsmsUnitCellScanBase;
import com.ideal.manage.esms.bean.project.*;
import com.ideal.manage.esms.bean.sys.Parameter;
import com.ideal.manage.esms.bean.sys.User;
import com.ideal.manage.esms.config.shiro.MyShiroRealm;
import com.ideal.manage.esms.jpa.JpaRepositoryImpl;
import com.ideal.manage.esms.repository.diagnostic.StadningBookInfoRepository;
import com.ideal.manage.esms.repository.monitor.UnitCellDataScanBaseRepository;
import com.ideal.manage.esms.repository.programme.ParameterInfoRepository;
import com.ideal.manage.esms.repository.project.AccountPropertyRepository;
import com.ideal.manage.esms.repository.project.EquipmentInfoRepository;
import com.ideal.manage.esms.repository.project.EquipmentManageRepository;
import com.ideal.manage.esms.repository.project.ProjectManageRepository;
import com.ideal.manage.esms.repository.system.ParameterRepository;
import com.ideal.manage.esms.repository.system.UserProjectRepository;
import com.ideal.manage.esms.repository.system.UserRepository;
import com.ideal.manage.esms.service.diagnostic.DiagnoseResultInfoService;
import com.ideal.manage.esms.service.system.UnitCellDataScanService;
import com.ideal.manage.esms.util.ElasticsearchUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.elasticsearch.search.SearchHit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 监控Service
 * Created By Dai On 2018-03-26
 */
@Service
public class MonitorService {

    private Logger logger = LoggerFactory.getLogger(MonitorService.class);

    @Autowired
    private ProjectManageRepository projectManageRepository;
    @Autowired
    private EquipmentManageRepository equipmentManageRepository;
    @Autowired
    private UserProjectRepository userProjectRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private ParameterInfoRepository parameterInfoRepository;
    @Autowired
    private AccountPropertyRepository accountPropertyRepository;
    @Autowired
    private StadningBookInfoRepository stadningBookInfoRepository;
    @Autowired
    private EquipmentInfoRepository equipmentInfoRepository;
    @Autowired
    private ParameterRepository parameterRepository;
    @Autowired
    private DiagnoseResultInfoService diagnoseResultInfoService;
    @Autowired
    private UnitCellDataScanService unitCellDataScanService;
    @Autowired
    private UnitCellDataScanBaseRepository unitCellDataScanBaseRepository;

    private JpaRepositoryImpl<DiagnoseResultInfo, String> diagnoseResultInfoRepository;
    @Autowired
    private EntityManager entityManager;
    @PostConstruct
    public void init() {
        this.diagnoseResultInfoRepository = new JpaRepositoryImpl<>(DiagnoseResultInfo.class, entityManager);
    }

    /**
     * 系统监控
     *
     * @return 返回 ztree节点
     */
    public List<JSONObject> getMonitorList(String name) {
        List<JSONObject> list = new ArrayList<>();
        // 1. 先把所有的项目加入list
        List<ProjectManage> projectManageList = new ArrayList<>();
        //获取当前登录用户
        MyShiroRealm.ShiroUser shiroUser = (MyShiroRealm.ShiroUser) SecurityUtils.getSubject().getPrincipal();
        User user = userRepository.findOne(shiroUser.getId());
        if (StringUtils.isBlank(name)) {
            projectManageList = userProjectRepository.findProjectByUser(user);
        } else {
            projectManageList = userProjectRepository.findProjectByUserAndName(user, name);
        }
        if (projectManageList.size() < 1) {
            return null;
        }
        projectManageList.forEach(projectManage -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", projectManage.getId());
            jsonObject.put("pId", 0L);
            jsonObject.put("name", projectManage.getName());
            jsonObject.put("type", 0L);
            jsonObject.put("open", true);
            list.add(jsonObject);
        });
        // 2. 找到所有的设备放到list
        List<EquipmentManage> equipmentManageList = equipmentManageRepository.findByProjects(projectManageList);
        equipmentManageList.forEach(equipmentManage -> {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id", equipmentManage.getId());
            if (equipmentManage.getParent() == null) {
                jsonObject.put("pId", equipmentManage.getProject().getId());
            } else {
                jsonObject.put("pId", equipmentManage.getParent().getId());
            }
            jsonObject.put("name", equipmentManage.getName());
            jsonObject.put("type", equipmentManage.getEquipmentType());
            int type = Integer.parseInt(equipmentManage.getEquipmentType());
            jsonObject.put("open", false);
            list.add(jsonObject);
        });
        return list;
    }

    /**
     * 根据id获取type
     *
     * @param id
     * @return
     */
    public String getType(String id) {
        return equipmentManageRepository.findOne(id).getEquipmentType();
    }

    /**
     * 根据id刷新 可储蓄电量
     *
     * @param id
     * @return
     */
    public String refreshCouldSavingElectricity(String id) {
        Random random = new Random();
        return String.format("%.2f", random.nextDouble() * 100000);
    }

    /**
     * 根据id刷新 总容量
     *
     * @param id
     * @return
     */
    public String refreshTotalElectricity(String id) {
        Random random = new Random();
        return String.format("%.2f", random.nextDouble() * 100000);
    }


//    ----------------------------------------- 电 池 包 -----------------------------------------


    /**
     * 实时监控 -> 电池包监控
     *
     * @param equipmentType
     * @return
     */
    public List<ParameterInfo> findListByTypeForMonitor(String equipmentType, EquipmentManage equipmentManage) {
        Integer parameterType = null;
        // 1. 获取所有 需要显示 的测点参数
        // 需要做这一步是因为 设备管理 表中的设备类型 和 测点参数 表中的设备类型值代表的意义不一致
        switch (equipmentType) {

            // 电池单体
            case "4":
                parameterType = 5;
                break;
            default:
                return null;
        }
        List<ParameterInfo> list = parameterInfoRepository.findListByTypeForMonitor(parameterType);
        // 2. 把这些参数分类
        // 4)累计 // 这个是累计的分组
        List<ParameterInfo> sumList =
                list.stream().filter(parameterInfo -> parameterInfo.getEsAggsMethod().toString().equals("1")).collect(Collectors.toList());
        // 获取到了以后就移除
        list.removeAll(sumList);
        // 1) 实时  // 这个是实时的分组
        List<ParameterInfo> nowList =
                list.stream().filter(parameterInfo -> parameterInfo.getEsAggsMethod().toString().equals("3")).collect(Collectors.toList());
        // 获取到了以后就移除
        list.removeAll(nowList);
        // 3) 今日  // 这个是今日的分组 (包括今日、最大、最小、极差、平均)
        List<ParameterInfo> todayList = new ArrayList<>();
        todayList.addAll(list);
        // 获取到了以后就移除
        list.removeAll(todayList);
        // 3. 获取值
        sumList = ElasticsearchUtils.getSumValue(sumList, equipmentManage);
        todayList = ElasticsearchUtils.getTodayValue(todayList, equipmentManage);
        //将过滤后的数据(指定电池单体,实时的参数测点配置数据)
        nowList = ElasticsearchUtils.getNowValue(nowList, equipmentManage);
        list.addAll(sumList);
        list.addAll(todayList);
        list.addAll(nowList);
        // 4. 返回
        return list;
    }


    /**
     * 实时监控 -> 设备状态监控
     *
     * @param equipmentType
     * @return
     */
    public List<EquipmentInfo> findEquipmentListByTypeForMointor(String equipmentType, EquipmentManage equipmentManage) {
        Integer objName = null;
        // 1. 获取所有 需要显示 的测点参数
        switch (equipmentType) { // 需要做这一步是因为 设备管理 表中的设备类型 和 测点参数 表中的设备类型值代表的意义不一致
            case "1":   // 变流器
                objName = 4;
                break;
            case "2":   // 电池包
                objName = 2;
                break;
            case "3":   // 电池模组
                objName = 3;
                break;
            case "4":   // 电池单体
                objName = 5;
                break;
            default:
                break;
        }
        List<EquipmentInfo> list = equipmentInfoRepository.findListByTypeForMonitor(objName);
        for (EquipmentInfo equipmentInfo : list) {
            List<EquipmentStatus> equipmentStatuses = new ArrayList<>();
            String status = equipmentInfo.getStatus();
            String[] value = status.split("\\|");
            int length = value.length;
            for (int i = 0; i < value.length; i++) {
                String[] data = value[i].split("\\=");
                EquipmentStatus equipmentStatus = new EquipmentStatus();
                equipmentStatus.setId(equipmentInfo.getId());
                equipmentStatus.setCode(equipmentInfo.getCode());
                equipmentStatus.setStatus(Integer.parseInt(data[0]));
                equipmentStatus.setText(data[1]);
                equipmentStatuses.add(equipmentStatus);
            }
            equipmentInfo.setLength(length);
            equipmentInfo.setList(equipmentStatuses);
        }
        //获得实时设备状态
        list = ElasticsearchUtils.getEquipmentInfoNowValue(list, equipmentManage);
        // 4. 返回
        return list;
    }

    /**
     * 实时数据 -> 模组监控
     *
     * @param equipmentManage
     * @return
     */
    public List<JSONObject> monitorGroupList(EquipmentManage equipmentManage) {
        ProjectManage projectManage = equipmentManage.getProject();
        // 1. 找到所有的电池单体
        List<EquipmentManage> groupList = equipmentManageRepository.findByParentId(equipmentManage.getId());
        List<EquipmentManage> batteryList = equipmentManageRepository.findBatterysByGroup(groupList);
        // 2. 获取电压的es的name
        ParameterInfo voltageParameter = parameterInfoRepository.findParameterInfoByNameAndType("电压", 6, 1, 0);
        ParameterInfo flowParameter = parameterInfoRepository.findParameterInfoByNameAndType("电流", 6, 3, 0);
        // 3. 获取时间范围
        Long startTime = System.currentTimeMillis() - 4000;
        List<JSONObject> result = ElasticsearchUtils.monitorGroupList(groupList, projectManage.getIp(), voltageParameter, startTime, new ArrayList<JSONObject>());
        result = ElasticsearchUtils.monitorGroupList(groupList, projectManage.getIp(), flowParameter, startTime, result);
        // 4. 返回
        return result;
    }


    /**
     * 台账信息
     *
     * @param equipmentManage
     * @return
     */
    public List<AccountProperty> accountPropertyList(EquipmentManage equipmentManage, int type, ProjectManage projectManage) {
        int objName = 1;    //项目
        if (equipmentManage != null) {
            if (equipmentManage.getEquipmentType().equals("1")) {    //变流器
                objName = 2;
            } else if (equipmentManage.getEquipmentType().equals("2")) { //电池包
                objName = 3;
            }
        }
        // 1. 找到所有的台账配置
        List<AccountProperty> result = accountPropertyRepository.findByObjNameAndParameterType(objName, type);
        if (result.size() < 1) {
            return null;
        }
        // 2. 找到所有的值
        List<StadningBookInfo> stadningBookInfos = null;
        if (objName > 1) {
            stadningBookInfos = stadningBookInfoRepository.findByAccountPropertyAndEquipmentManage(result, equipmentManage);
        } else {
            stadningBookInfos = stadningBookInfoRepository.findByAccountPropertyAndProjectManage(result, projectManage);
        }
        // 3. 塞进去
        for (AccountProperty accountProperty : result) {
            for (StadningBookInfo stadningBookInfo : stadningBookInfos) {
                if (accountProperty.getId().equals(stadningBookInfo.getAccount().getId())) {
                    accountProperty.setValue(stadningBookInfo.getVal());
                    break;
                }
            }
        }
        return result;
    }

    /**
     * 实时监控 - 单体电压/温度 排名 列表
     *
     * @return
     */
    public List getVoltageOrTemperatureData(String id, String name, int obj_name, int obj_type, int is_show) {
        // 1. 找到所有的电池单体
        EquipmentManage equipmentManage = equipmentManageRepository.findOne(id);
        ProjectManage projectManage = equipmentManage.getProject();
        List<EquipmentManage> groupList = equipmentManageRepository.findByParentId(id);
        List<EquipmentManage> batteryList = equipmentManageRepository.findBatterysByGroup(groupList);
        // 2. 获取es的name
        ParameterInfo parameterInfo = parameterInfoRepository.findParameterInfoByNameAndType(name, obj_name, obj_type, is_show);
        List list = new ArrayList();
        if (parameterInfo == null) {
            return list;
        }
        String field = parameterInfo.getEsName();
        if (batteryList.size() > 0) {
            if (batteryList.size() >= 5) {
                list = ElasticsearchUtils.getTopAndLowValue(batteryList, field, projectManage.getIp(), 3);
            } else {
                list = ElasticsearchUtils.getTopAndLowValue(batteryList, field, projectManage.getIp(), batteryList.size());
            }
        } else {
            if (groupList.size() >= 5) {
                list = ElasticsearchUtils.getTopAndLowValue(groupList, field, projectManage.getIp(), 3);
            } else {
                list = ElasticsearchUtils.getTopAndLowValue(groupList, field, projectManage.getIp(), groupList.size());
            }
        }
        return list;
    }

    /**
     * 实时监控 - 单体电压/温度 排名 柱状图
     *
     * @param id
     * @return
     */
    public Map getTopAndBottom(String id) {
        // 1. 找到所有的电池单体
        EquipmentManage equipmentManage = equipmentManageRepository.findOne(id);
        ProjectManage projectManage = equipmentManage.getProject();
        List<EquipmentManage> groupList = equipmentManageRepository.findByParentId(id);
        List<EquipmentManage> batteryList = equipmentManageRepository.findBatterysByGroup(groupList);
        Map result = new HashMap();

        return result;
    }

    /**
     * 实时监控 - 项目充电放电量、电费  今日曲线
     *
     * @param id
     * @return
     */
    public Map getTodayElectricity(String id) {
        // 1. 找到项目
        ProjectManage projectManage = projectManageRepository.findOne(id);
        // 2. 获取充放电量的es的name
        ParameterInfo chargeParameter = parameterInfoRepository.findParameterInfoByNameAndType("今日充电量", 1, 2, 0);
        String chargeField = chargeParameter == null ? "" : chargeParameter.getEsName();
        ParameterInfo dischargeParameter = parameterInfoRepository.findParameterInfoByNameAndType("今日放电量", 1, 2, 0);
        String dischargeField = dischargeParameter == null ? "" : dischargeParameter.getEsName();
        // 3. 获取时间范围
        //今天零点零分零秒的毫秒数;
        Long startTime = System.currentTimeMillis() / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
        Long endTime = startTime + 24 * 60 * 60 * 1000 - 1;
        // 4. 最终返回的结果 result
        Map result = new HashMap();
        // 4.1充电量
        JSONObject chargeList = ElasticsearchUtils.getDateHistogramSum(
                "", chargeField, projectManage.getIp(), "hour", startTime, endTime);
        result.put("chargeList", chargeList);
        // 4.2 放电量
        JSONObject dischargeList = ElasticsearchUtils.getDateHistogramSum(
                "", dischargeField, projectManage.getIp(), "hour", startTime, endTime);
        result.put("dischargeList", dischargeList);
        //省电费
        JSONObject chargePrice = countChargePrice(chargeList, dischargeList, id);
        result.put("chargePrice", chargePrice);
        //耗电费
        JSONObject dischargePrice = countDischargePrice(dischargeList, id);
        result.put("dischargePrice", dischargePrice);
        return result;
    }

    /**
     * 省电费计算
     *
     * @param chargeList
     * @param dischargeList
     * @return
     */
    public JSONObject countChargePrice(JSONObject chargeList, JSONObject dischargeList, String projectId) {
        JSONObject chargePrice = new JSONObject();
        Double price = 0.0;
        Double price1 = 0.0;
        Double price2 = 0.0;
        Double price3 = 0.0;
        List<AccountProperty> accountProperty = accountPropertyRepository.findByObjNameAndParameterType(1, 6);
        for (AccountProperty property : accountProperty) {
            if (property.getName().contains("尖")) {
                StadningBookInfo bookInfo = stadningBookInfoRepository.findByAccountId(property.getId(), projectId);
                if (bookInfo != null) {
                    price = Double.parseDouble(StringUtils.isBlank(bookInfo.getVal()) ? "0.0" : bookInfo.getVal());
                }
            } else if (property.getName().contains("峰")) {
                StadningBookInfo bookInfo = stadningBookInfoRepository.findByAccountId(property.getId(), projectId);
                if (bookInfo != null) {
                    price1 = Double.parseDouble(StringUtils.isBlank(bookInfo.getVal()) ? "0.0" : bookInfo.getVal());
                }
            } else if (property.getName().contains("平")) {
                StadningBookInfo bookInfo = stadningBookInfoRepository.findByAccountId(property.getId(), projectId);
                if (bookInfo != null) {
                    price2 = Double.parseDouble(StringUtils.isBlank(bookInfo.getVal()) ? "0.0" : bookInfo.getVal());
                }
            } else if (property.getName().contains("谷")) {
                StadningBookInfo bookInfo = stadningBookInfoRepository.findByAccountId(property.getId(), projectId);
                if (bookInfo != null) {
                    price3 = Double.parseDouble(StringUtils.isBlank(bookInfo.getVal()) ? "0.0" : bookInfo.getVal());
                }
            }
        }

        for (Map.Entry<String, Object> charge : chargeList.entrySet()) {
            String chargeTime = charge.getKey();
            Double chargeValue = Double.parseDouble(charge.getValue().toString());
            String[] data = chargeTime.split(":");
            int hour = Integer.parseInt(data[0]);
            Double val = 0.0;
            for (Map.Entry<String, Object> discharge : dischargeList.entrySet()) {
                String dischargeTime = discharge.getKey();
                if (dischargeTime.equals(chargeTime)) {
                    Double dischargeValue = Double.parseDouble(discharge.getValue().toString());
                    if (hour >= 12 && hour < 13) {
                        val = (dischargeValue - chargeValue) * price;
                        chargePrice.put(chargeTime, val);
                    } else if ((hour >= 10 && hour < 12) || (hour >= 13 && hour < 15)) {
                        val = (dischargeValue - chargeValue) * price1;
                        chargePrice.put(chargeTime, val);
                    } else if ((hour >= 6 && hour < 10) || (hour >= 15 && hour < 21)) {
                        val = (dischargeValue - chargeValue) * price2;
                        chargePrice.put(chargeTime, val);
                    } else if (hour >= 21 || hour < 6) {
                        val = (dischargeValue - chargeValue) * price3;
                        chargePrice.put(chargeTime, val);
                    }
                }
            }
        }
        return chargePrice;
    }

    /**
     * 耗电费计算
     *
     * @param object
     * @return
     */
    public JSONObject countDischargePrice(JSONObject object, String projectId) {
        JSONObject dischargePrice = new JSONObject();
        Double price = 0.0;
        Double price1 = 0.0;
        Double price2 = 0.0;
        Double price3 = 0.0;
        List<AccountProperty> accountProperty = accountPropertyRepository.findByObjNameAndParameterType(1, 6);
        for (AccountProperty property : accountProperty) {
            if (property.getName().contains("尖")) {
                StadningBookInfo bookInfo = stadningBookInfoRepository.findByAccountId(property.getId(), projectId);
                if (bookInfo != null) {
                    price = Double.parseDouble(StringUtils.isBlank(bookInfo.getVal()) ? "0.0" : bookInfo.getVal());
                }
            } else if (property.getName().contains("峰")) {
                StadningBookInfo bookInfo = stadningBookInfoRepository.findByAccountId(property.getId(), projectId);
                if (bookInfo != null) {
                    price1 = Double.parseDouble(StringUtils.isBlank(bookInfo.getVal()) ? "0.0" : bookInfo.getVal());
                }
            } else if (property.getName().contains("平")) {
                StadningBookInfo bookInfo = stadningBookInfoRepository.findByAccountId(property.getId(), projectId);
                if (bookInfo != null) {
                    price2 = Double.parseDouble(StringUtils.isBlank(bookInfo.getVal()) ? "0.0" : bookInfo.getVal());
                }
            } else if (property.getName().contains("谷")) {
                StadningBookInfo bookInfo = stadningBookInfoRepository.findByAccountId(property.getId(), projectId);
                if (bookInfo != null) {
                    price3 = Double.parseDouble(StringUtils.isBlank(bookInfo.getVal()) ? "0.0" : bookInfo.getVal());
                }
            }
        }
        for (Map.Entry<String, Object> entry : object.entrySet()) {
            String time = entry.getKey();
            Double value = Double.parseDouble(entry.getValue().toString());
            String[] data = time.split(":");
            int hour = Integer.parseInt(data[0]);
            Double val = 0.0;
            if (hour >= 12 && hour < 13) {
                val = value * price;
                dischargePrice.put(time, (val > 0) ? -val : val);
            } else if ((hour >= 10 && hour < 12) || (hour >= 13 && hour < 15)) {
                val = value * price1;
                dischargePrice.put(time, (val > 0) ? -val : val);
            } else if ((hour >= 6 && hour < 10) || (hour >= 15 && hour < 21)) {
                val = value * price2;
                dischargePrice.put(time, (val > 0) ? -val : val);
            } else if (hour >= 21 || hour < 6) {
                val = value * price3;
                dischargePrice.put(time, (val > 0) ? -val : val);
            }
        }
        return dischargePrice;
    }

    /**
     * 实时监控 - 电压/电流/SOC  今日曲线
     *
     * @param id
     * @return
     */
    public Map getTodayLine(String id) throws ParseException {
        // 找到电池包
        EquipmentManage equipmentManage = equipmentManageRepository.findOne(id);
        // 获取项目
        ProjectManage projectManage = equipmentManage.getProject();
        // 获取电池模组下的所有的电池单体
        List<EquipmentManage> allBattery = equipmentManageRepository.findByAllBattery(id);
        List<String> code = new ArrayList<>();
        String macid = allBattery.get(0).getCode().substring(0, allBattery.get(0).getCode().indexOf("#"));
        for (EquipmentManage eq : allBattery) {
            code.add(eq.getCode().substring(eq.getCode().indexOf("#") + 1, eq.getCode().length()) + "Volt");
        }
        //今天零点零分零秒的毫秒数;
        Long startTime = System.currentTimeMillis() / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
        Long endTime = startTime + 24 * 60 * 60 * 1000 - 1;

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH");
        long time = 1000L * 60L * 60L;

        // 格式化
        Date start = simpleDateFormat.parse(simpleDateFormat.format(startTime));
        Date end = simpleDateFormat.parse(simpleDateFormat.format(endTime));
        // 创建查询条件 电压
        List<EsmsUnitCellScanBase> bases = unitCellDataScanBaseRepository.findByGroupBattery(macid, code, projectManage.getIp(), start, end);
        //  去重
        List<String> codes = new ArrayList<>();

            Query query = entityManager.createNativeQuery("SELECT AVG(d.result_val) as val, FROM_UNIXTIME(time / 1000, '%Y-%m-%d %H') hours " +
                    " FROM esms_diagnose_batch b,  esms_diagnose_result_info d " +
                    " WHERE b.id = d.batch_id AND d.set_val = 'soc' AND b.`time` BETWEEN ? AND ? GROUP BY hours ORDER BY b.`time` DESC");
            query.setParameter(1, startTime);
            query.setParameter(2, endTime);
        List<Object[]> list = query.getResultList();

        Map result = new HashMap();
        JSONObject voltageList = new JSONObject();
        JSONObject socList = new JSONObject();

        Float value = 0.0F;
        String name = "";

        // 最终返回的结果 result
        //定义时间段
        int k = 24;
        for (int j = 0; j < k; j++) {
            for (EsmsUnitCellScanBase es : bases) {
                long dataTime = format.parse(format.format(es.getDateTime())).getTime();

                if (startTime + time * j == dataTime) {
                    if(codes.contains(es.getCellName())){
                        continue;
                    }
                    codes.add(es.getCellName());
                    value += es.getVal();

                    name = new SimpleDateFormat("HH:mm").format(format.parse(format.format(es.getDateTime())));

                }
                name = new SimpleDateFormat("HH:mm").format(new Date(startTime + time * j));
            }

            codes.clear();
            voltageList.put(name, value* 0.001F);
            name = "";
            value = 0.0F;

            for (Object[] values : list) {
                String key = (String) values[1];
                double val = Utils.toDouble((Double) values[0]);

                long dataTime = format.parse(key).getTime();

                if (startTime + time * j == dataTime) {
                    value = Float.valueOf(String.valueOf(val));
                    name = new SimpleDateFormat("HH:mm").format(format.parse(key));

                }
                name = new SimpleDateFormat("HH:mm").format(new Date(startTime + time * j));

            }
            socList.put(name, value);
            name = "";
            value = 0.0F;
        }
        result.put("voltageList", voltageList);
        result.put("socList", socList);

        return result;
    }

    /**
     * 实时监控 - 电压/温度 今日极值/极差曲线
     *
     * @param id
     * @return
     */
    public Map getTodayBar(String id) throws ParseException {
        // 1. 找到电池包
        EquipmentManage equipmentManage = equipmentManageRepository.findOne(id);
        ProjectManage projectManage = equipmentManage.getProject();
        // 获取电池模组下的所有的电池单体
        List<EquipmentManage> allBattery = equipmentManageRepository.findByAllBattery(id);
        List<String> code = new ArrayList<>();
        String macid = allBattery.get(0).getCode().substring(0, allBattery.get(0).getCode().indexOf("#"));
        for (EquipmentManage eq : allBattery) {
            code.add(eq.getCode().substring(eq.getCode().indexOf("#") + 1, eq.getCode().length()) + "Volt");
        }

        //今天零点零分零秒的毫秒数;
        Long startTime = System.currentTimeMillis() / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
        Long endTime = startTime + 24 * 60 * 60 * 1000 - 1;

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH");
        long time = 1000L * 60L * 60L;

        //格式化
        Date start = simpleDateFormat.parse(simpleDateFormat.format(startTime));
        Date end = simpleDateFormat.parse(simpleDateFormat.format(endTime));
        // 将每个电池单体在一天的时间段(如:00:00时间段)做累加,在将其做最小值 最大值的判断
        Map<String, Float> data = new HashMap<>();
//        List<String>codes = new ArrayList<>();
        Float value = 0.0F;
        String name = "";
        for (int i = 0; i < code.size(); i++) {
            List<EsmsUnitCellScanBase> byOneBattery = unitCellDataScanBaseRepository.findByOneBatutery(macid, code.get(i), projectManage.getIp(), start, end);
            if (byOneBattery.size() == 0) {
                continue;
            }
            int k = 24;
            for (int j = 0; j < k; j++) {
                for (EsmsUnitCellScanBase es : byOneBattery) {
                    long dataTime = format.parse(format.format(es.getDateTime())).getTime();
                    if (startTime + time * j == dataTime) {
                        name = new SimpleDateFormat("HH:mm").format(format.parse(format.format(es.getDateTime()))) + code.get(i);
                        value = es.getVal();
                    }
                    name = new SimpleDateFormat("HH:mm").format(new Date(startTime + time * j)) + code.get(i);
                }
                data.put(name, value* 0.001F);
                value = 0.0F;
                name = "";
            }
        }
        JSONObject voltageLowList = new JSONObject();
        JSONObject voltageDifferenceList = new JSONObject();
        List<Float> datas = new ArrayList<>();
        int o = 24;
        for (int j = 0; j < o; j++) {
            for (Map.Entry<String, Float> entry : data.entrySet()) {
                String dateTime = entry.getKey().substring(0, entry.getKey().indexOf("C"));
                name = new SimpleDateFormat("HH:mm").format(new Date(startTime + time * j));
                if (name.equals(dateTime)) {
                    datas.add(entry.getValue());
                } else {
                    continue;
                }
            }
            value = Collections.min(datas);
            voltageLowList.put(name, value);
            value = 0.0F;
            value =  (Collections.max(datas) - Collections.min(datas));
            voltageDifferenceList.put(name, value);
            value = 0.0F;
            name = "";
            datas.clear();
        }

        //  最终返回的结果 result
        Map result = new HashMap();
        result.put("voltageLowList", voltageLowList);
        result.put("voltageDifferenceList", voltageDifferenceList);
        return result;
    }

    /**
     * 实时监控 - 模组监控 - 柱状图
     *
     * @param id
     * @return
     */
    public Map packageInfo(String id) {
        String type = "";
        List<EquipmentManage> groupList = new ArrayList<>();
        List<EquipmentManage> batteryList = new ArrayList<>();
        ProjectManage projectManage = new ProjectManage();
        // 1. 找到所有的电池单体
        EquipmentManage equipmentManage = equipmentManageRepository.findOne(id);
        if (equipmentManage != null) {
            type = "1";//电池包
            projectManage = equipmentManage.getProject();
            groupList = equipmentManageRepository.findByParentId(id);
            batteryList = equipmentManageRepository.findBatterysByGroup(groupList);
        } else {
            type = "2";//项目
            projectManage = projectManageRepository.findOne(id);
            batteryList = equipmentManageRepository.findEquipments(id, "4");
        }
        // 2. 获取电压的es的name
        ParameterInfo voltageParameter = parameterInfoRepository.findParameterInfoByNameAndType("电压", 6, 1, 0);
        String voltageField = voltageParameter == null ? "" : voltageParameter.getEsName();
        ParameterInfo temperatureParameter = parameterInfoRepository.findParameterInfoByNameAndType("温度", 6, 4, 0);
        String temperatureField = temperatureParameter == null ? "" : temperatureParameter.getEsName();
        // 3. 最终返回的结果 result
        Map result = new HashMap();
        JSONObject voltageHighList = ElasticsearchUtils.packageInfo(batteryList, voltageField, projectManage.getIp(), "DESC", type);
        JSONObject voltageLowList = ElasticsearchUtils.packageInfo(batteryList, voltageField, projectManage.getIp(), "ASC", type);
        JSONObject temperatureHighList = ElasticsearchUtils.packageInfo(batteryList, temperatureField, projectManage.getIp(), "DESC", type);
        JSONObject temperatureLowList = ElasticsearchUtils.packageInfo(batteryList, temperatureField, projectManage.getIp(), "ASC", type);
        result.put("voltageHighList", voltageHighList);
        result.put("voltageLowList", voltageLowList);
        result.put("temperatureHighList", temperatureHighList);
        result.put("temperatureLowList", temperatureLowList);
        return result;
    }

    /**
     * 历史数据
     *
     * @param id         设备id
     * @param objType    测点类别
     * @param name       测点名称
     * @param ranges     时间范围
     * @param freque     显示密度
     * @param show_type  显示类别
     * @param start_time 开始时间
     * @param end_time   结束时间
     * @return
     */
    public Map historyDataEquipment(String id, int objType, String name, String ranges,
                                    String freque, String show_type, String start_time, String end_time) {

        // 1. 准备一个返回的结果~
        Map map = new HashMap();
        String title = "";
        // 2. 获取当前设备
        EquipmentManage equipmentManage = equipmentManageRepository.findOne(id);
        ProjectManage projectManage = new ProjectManage();
        // 3. 获取要查询的字段
        int objName = 1;
        String code = "";
        String ip = "";
        if (equipmentManage != null) {
            //变流器
            if ("1".equals(equipmentManage.getEquipmentType())) {
                objName = 4;
                //电池包
            } else if ("2".equals(equipmentManage.getEquipmentType())) {
                objName = 2;
                //电池模组
            } else if ("3".equals(equipmentManage.getEquipmentType())) {
                objName = 3;
                //电池单体
            } else if ("4".equals(equipmentManage.getEquipmentType())) {
                objName = 5;
            }
            code = equipmentManage.getCode();
            ip = equipmentManage.getProject().getIp();
        } else {
            projectManage = projectManageRepository.findOne(id);
            ip = projectManage.getIp();
        }
        ParameterInfo parameterInfo = null;
        //获取对应配置的参数测点
        if ("单体电压极值和极差".equals(name)) {
            name = "极值和极差";
            parameterInfo = new ParameterInfo();
            parameterInfo.setName(name);
            parameterInfo.setEsName("Volt");

            show_type = "difference";
        } else {
            parameterInfo = parameterInfoRepository.findOneByNameAndTypeAndObjName(name, objType, objName);
        }
        // 4. 获取时间 这边还没问清这个时间范围到底是怎么样的
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Long startTime = 0L;
        Long endTime = 0L;
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        // 根据时间范围
        // 根据时间范围
        List timeRange = getTimeRange(ranges, startTime, endTime, calendar, equipmentManage, title, simpleDateFormat, name, projectManage, start_time, end_time);
        startTime = (Long) timeRange.get(0);
        endTime = (Long) timeRange.get(1);
        title = timeRange.get(2).toString();
        // 5. 先把title放进去
        map.put("title", title);
        // 6. 如果没有找到对应的es_name就直接返回
        if (parameterInfo == null) {
            return map;
        }
        // 7. 判断调用的是什么，然后获取返回值
        JSONObject jsonObject = new JSONObject();
        String esName = parameterInfo.getEsName();
        switch (show_type) {
            case "avg":
                try {
                    jsonObject = unitCellDataScanService.getScanBatteryData(code, esName, ip, freque, startTime, endTime, "avg");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            case "min":
                try {
                    jsonObject = unitCellDataScanService.getScanBatteryData(code, esName, ip, freque, startTime, endTime, "min");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            case "max":
                try {
                    jsonObject = unitCellDataScanService.getScanBatteryData(code, esName, ip, freque, startTime, endTime, "max");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            case "now":
                try {
                    jsonObject = unitCellDataScanService.getScanBatteryData(code, esName, ip, freque, startTime, endTime, "min");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            case "difference":
                try {
                    map = unitCellDataScanService.getMinAndMax(code, esName, ip, freque, startTime, endTime, "min");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            default:
                return null;
        }
        if ("difference".equals(show_type)) {
            map.put("title", title);
            return map;
        } else {
            map.put("jsonObject", jsonObject);
        }
        // 7. 放进去
        return map;
    }

    /**
     * 频数频率分布图
     *
     * @param id   电池包ID
     * @param name 查询的名字
     * @return
     */
    public JSONObject findFrequencyList(String id, String name) {
        JSONObject result = new JSONObject();
        // 1. 找到电池包下所有的电池单体
        List<EquipmentManage> groupList = equipmentManageRepository.findByParentId(id);
        List<EquipmentManage> batteryList = equipmentManageRepository.findBatterysByGroup(groupList);
        // 2. 找到所有单体最近近时间的一条数据
        int count_0 = 0, count_10 = 0, count_20 = 0, count_30 = 0,
                count_40 = 0, count_50 = 0, count_60 = 0, count_70 = 0,
                count_80 = 0, count_90 = 0, count_100 = 0, count = 0;
        for (EquipmentManage equipmentManage : batteryList) {
            String battery_id = equipmentManage.getId();
            Double value = diagnoseResultInfoService.getValue(battery_id, name);
            if (value < 10 && value > 0) {
                count_10++;
            } else if (value < 20 && value > 0) {
                count_20++;
            } else if (value < 30 && value > 0) {
                count_30++;
            } else if (value < 40 && value > 0) {
                count_40++;
            } else if (value < 50 && value > 0) {
                count_50++;
            } else if (value < 60 && value > 0) {
                count_60++;
            } else if (value < 70 && value > 0) {
                count_70++;
            } else if (value < 80 && value > 0) {
                count_80++;
            } else if (value < 90 && value > 0) {
                count_90++;
            } else if (value < 100 && value > 0) {
                count_100++;
            } else {
                count_0++;
            }
            count++;
        }
        // 3. 放入频数
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("0%", count_0);
        jsonObject.put("10%", count_10);
        jsonObject.put("20%", count_20);
        jsonObject.put("30%", count_30);
        jsonObject.put("40%", count_40);
        jsonObject.put("50%", count_50);
        jsonObject.put("60%", count_60);
        jsonObject.put("70%", count_70);
        jsonObject.put("80%", count_80);
        jsonObject.put("90%", count_90);
        jsonObject.put("100%", count_100);
        result.put("frequency", jsonObject);
        // 4. 放入频率
        jsonObject = new JSONObject();
        if (count == 0) {
            jsonObject.put("0%", 0);
            jsonObject.put("10%", 0);
            jsonObject.put("20%", 0);
            jsonObject.put("30%", 0);
            jsonObject.put("40%", 0);
            jsonObject.put("50%", 0);
            jsonObject.put("60%", 0);
            jsonObject.put("70%", 0);
            jsonObject.put("80%", 0);
            jsonObject.put("90%", 0);
            jsonObject.put("100%", 0);
        } else {
            jsonObject.put("0%", count_0 / count * 100);
            jsonObject.put("10%", count_10 / count * 100);
            jsonObject.put("20%", count_20 / count * 100);
            jsonObject.put("30%", count_30 / count * 100);
            jsonObject.put("40%", count_40 / count * 100);
            jsonObject.put("50%", count_50 / count * 100);
            jsonObject.put("60%", count_60 / count * 100);
            jsonObject.put("70%", count_70 / count * 100);
            jsonObject.put("80%", count_80 / count * 100);
            jsonObject.put("90%", count_90 / count * 100);
            jsonObject.put("100%", count_100 / count * 100);
        }
        result.put("rate", jsonObject);
        // 5. 获取时间
        result.put("time_value", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        // 6. 获取 算法的value
        // SOC
        if ("dtsoc".equals(name)) {
            Double coc = diagnoseResultInfoService.getValue(id, "coc");
            Double lastcoc = diagnoseResultInfoService.getLastValue(id, "coc");
            Double soc = diagnoseResultInfoService.getValue(id, "soc");
            Double lastsoc = diagnoseResultInfoService.getLastValue(id, "soc");
            //塞值
            result.put("value", coc); //校准值
            result.put("change_value", coc - lastcoc);    //校准变化值
            result.put("offset_value", coc - soc);    //偏差值
            result.put("offset_change_value", (coc - soc) - (lastcoc - lastsoc));    //偏差变化值
        }
        return result;
    }

//    ----------------------------------------- 电 池 包 End -----------------------------------------

    /**
     * 根据电池模组id找到所有单体电池的电压
     *
     * @param id
     * @return
     */
    public List<EquipmentManage> findBattery(String id) {
        // 1. 找到所有的电池单体
        //电池模组
        EquipmentManage equipmentManage = equipmentManageRepository.findOne(id);
        ProjectManage projectManage = equipmentManage.getProject();
        //电池单体
        List<EquipmentManage> batteryGroup = equipmentManageRepository.findByParentId(id);

        List<EquipmentManage> list = ElasticsearchUtils.getEquipmentManageNowValue(batteryGroup, projectManage);


        return list;
    }

    /**
     * 诊断接口2查询数据
     *
     * @param
     * @return
     */
    public JSONArray findDataPython2(EquipmentManage equipmentManage, Long startTime, Long endTime, JSONObject data) {
        JSONArray jsonArray = new JSONArray();
        String ip = data.getString("ip");
        String port = data.getString("port");
        String macid = data.getString("macid");
        String time = data.getString("time");
        List<ParameterInfo> list = new ArrayList<>();
        //电压的esname
        List<ParameterInfo> elecList = parameterInfoRepository.findByTypeAndObjName(1, 2);
        if (elecList.size() > 0) {
            for (ParameterInfo parameterInfo : elecList) {
                if (parameterInfo.getName().contains("单体电压")) {
                    list.add(parameterInfo);
                }
            }
        }

        //温度的esname
        List<ParameterInfo> temList = parameterInfoRepository.findByTypeAndObjName(3, 2);
        if (temList.size() > 0) {
            for (ParameterInfo parameterInfo : temList) {
                if (parameterInfo.getName().contains("电池温度")) {
                    list.add(parameterInfo);
                }
            }
        }

        ParameterInfo parameter = parameterInfoRepository.findOneByNameAndTypeAndObjName("电流", 2, 3);
        if (parameter != null) {
            list.add(parameter);
        }

        Set<String> fields = new HashSet<>();
        for (ParameterInfo parameterInfo : list) {
            fields.add(parameterInfo.getEsName());
        }

        // 2. 把这些参数分类
        List<ParameterInfo> nowList =   // 这个是实时的分组
                list.stream().filter(parameterInfo -> parameterInfo.getEsAggsMethod().toString().equals("3")).collect(Collectors.toList());
        // 获取到了以后就移除
        list.removeAll(nowList);

        // 3. 获取值
        SearchHit[] tenMillsHits = null;
        tenMillsHits = ElasticsearchUtils.getDataPython2Value(nowList, equipmentManage, startTime, endTime);
        jsonArray = getDataPython2(tenMillsHits, ip, port, macid, jsonArray, fields);
        // 4. 返回
        return jsonArray;
    }

    public JSONArray getDataPython2(SearchHit[] searchHits, String ip, String port, String macid, JSONArray jsonArray, Set<String> fields) {
        for (SearchHit hit : searchHits) {
            JSONObject jsonObject = new JSONObject();
            Map map = hit.getSourceAsMap();
            for (String str : fields) {
                long valueStr = 0;
                Object value = map.get(str);
                if (value != null) {
                    valueStr = Long.valueOf(String.valueOf(value)).longValue();
                    jsonObject.put(str, valueStr);
                    jsonObject.put("ip", ip);
                    jsonObject.put("port", port);
                    jsonObject.put("macid", macid);
                    jsonObject.put("time", map.get("time").toString());
                } else {
                    continue;
                }
            }
            jsonArray.add(jsonObject);
        }
        return jsonArray;
    }

    /**
     * 诊断接口5查询数据
     *
     * @param
     * @return
     */
    public JSONObject findDataPython5(EquipmentManage equipmentManage, Long time, JSONObject data) {
        List<ParameterInfo> list = new ArrayList<>();
        JSONObject jsonObject = new JSONObject();
        String ip = data.getString("ip");
        String port = data.getString("port");
        String macid = data.getString("macid");
        //电流的esname
        ParameterInfo info = parameterInfoRepository.findDataPython5("最大允许充电电流", 3L);
        if (info != null) {
            list.add(info);
        }
        ParameterInfo info1 = parameterInfoRepository.findDataPython5("充电电流请求值", 3L);
        if (info1 != null) {
            list.add(info1);
        }
        ParameterInfo info2 = parameterInfoRepository.findDataPython5("瞬态放电电流", 3L);
        if (info2 != null) {
            list.add(info2);
        }
        ParameterInfo info3 = parameterInfoRepository.findDataPython5("瞬态充电电流", 3L);
        if (info3 != null) {
            list.add(info3);
        }
        ParameterInfo info4 = parameterInfoRepository.findDataPython5("稳态放电电流", 3L);
        if (info4 != null) {
            list.add(info4);
        }
        ParameterInfo info5 = parameterInfoRepository.findDataPython5("稳态充电电流", 3L);
        if (info5 != null) {
            list.add(info5);
        }

        Set<String> fields = new HashSet<>();
        for (ParameterInfo parameterInfo : list) {
            fields.add(parameterInfo.getEsName());
        }

        // 3. 获取值
        SearchHit[] tenMillsHits = null;
        tenMillsHits = ElasticsearchUtils.getDataPython5Value(list, equipmentManage, time);
        if (tenMillsHits.length < 1) {
            for (String str : fields) {
                jsonObject.put(str, 0);
            }
            jsonObject.put("ip", ip);
            jsonObject.put("port", port);
            jsonObject.put("macid", macid);
            jsonObject.put("time", time);
        } else {
            SearchHit hit = tenMillsHits[0];
            Map map = hit.getSourceAsMap();
            for (String str : fields) {
                long valueStr = 0;
                Object value = map.get(str);
                if (value != null) {
                    valueStr = Long.valueOf(String.valueOf(value)).longValue();
                }
                jsonObject.put(str, valueStr);
            }
            jsonObject.put("ip", ip);
            jsonObject.put("port", port);
            jsonObject.put("macid", macid);
            jsonObject.put("time", time);
        }
        return jsonObject;
    }

    /**
     * 诊断接口4查询数据
     *
     * @param
     * @return
     */
    public JSONArray findDataPython4(EquipmentManage equipmentManage, Long startTime, Long endTime, JSONObject data) {
        JSONArray jsonArray = new JSONArray();
        String ip = data.getString("ip");
        String port = data.getString("port");
        String macid = data.getString("macid");
        String time = data.getString("time");
        List<ParameterInfo> list = new ArrayList<>();
        //电流的esname
        List<ParameterInfo> elecList = parameterInfoRepository.findByTypeAndObjName(1, 2);
        for (ParameterInfo parameterInfo : elecList) {
            if (parameterInfo.getName().contains("单体电压")) {
                list.add(parameterInfo);
            }
        }

        ParameterInfo parameter = parameterInfoRepository.findOneByNameAndTypeAndObjName("电流", 2, 3);
        if (parameter != null) {
            list.add(parameter);
        }

        Set<String> fields = new HashSet<>();
        for (ParameterInfo parameterInfo : list) {
            fields.add(parameterInfo.getEsName());
        }
        // 2. 把这些参数分类
        List<ParameterInfo> nowList =   // 这个是实时的分组
                list.stream().filter(parameterInfo -> parameterInfo.getEsAggsMethod().toString().equals("3")).collect(Collectors.toList());
        list.removeAll(nowList);        // 获取到了以后就移除

        // 3. 获取值
        SearchHit[] tenMillsHits = null;
        tenMillsHits = ElasticsearchUtils.getDataPython2Value(nowList, equipmentManage, startTime, endTime);
        for (SearchHit hit : tenMillsHits) {
            JSONObject jsonObject = new JSONObject();
            Map map = hit.getSourceAsMap();
            for (String str : fields) {
                Long valueStr = 0L;
                Object value = map.get(str);
                if (value != null) {
                    valueStr = Long.valueOf(String.valueOf(value));
                } else {
                    valueStr = 0L;
                }
                jsonObject.put(str, valueStr);
            }
            jsonObject.put("ip", ip);
            jsonObject.put("port", port);
            jsonObject.put("macid", macid);
            jsonObject.put("time", (map.get("time")));

            jsonArray.add(jsonObject);
        }
        // 4. 返回
        return jsonArray;
    }

    /**
     * 根据id 获取 最高最低的值
     *
     * @param id
     * @return
     */
    public JSONObject getHighAndLow(String id) {
        Parameter vol_low = parameterRepository.findByCodeAndName(id + "_vol_low", "vol_low");
        Parameter vol_high = parameterRepository.findByCodeAndName(id + "_vol_high", "vol_high");
        Parameter tmp_low = parameterRepository.findByCodeAndName(id + "_tmp_low", "tmp_low");
        Parameter tmp_high = parameterRepository.findByCodeAndName(id + "_tmp_high", "tmp_high");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("vol_low", vol_low == null ? "0.0" : vol_low.getName());
        jsonObject.put("vol_high", vol_high == null ? "0.0" : vol_high.getName());
        jsonObject.put("tmp_low", tmp_low == null ? "0.0" : tmp_low.getName());
        jsonObject.put("tmp_high", tmp_high == null ? "0.0" : tmp_high.getName());
        return jsonObject;
    }

    /**
     * 保存值
     *
     * @param id
     * @param name
     * @param val
     */
    public void saveHighAndLow(String id, String name, Double val) {
        Parameter parameter = parameterRepository.findByCodeAndName(id + "_" + name, name);
        //获取当前登录用户
        MyShiroRealm.ShiroUser shiroUser = (MyShiroRealm.ShiroUser) SecurityUtils.getSubject().getPrincipal();
        User user = userRepository.findOne(shiroUser.getId());
        if (parameter == null) {
            parameter = new Parameter();
            parameter.setCode(id + "_" + name);
            parameter.setRemark(name);
            Parameter parent = parameterRepository.findByCodeAndName("1060", "high_and_low");
            parameter.setParent(parent);
            parameter.setCreateTime(new Date());
            parameter.setCreateUser(user);
            parameter.setDelFlag(0L);
            parameter.setStatus(0L);    //并不知道这玩意儿是什么 = =
        }
        parameter.setLastUpdateTime(new Date());
        parameter.setLastUpdateUser(user);
        parameter.setName(val + "");
        parameterRepository.save(parameter);
    }

    /**
     * 电池模组模组监控
     *
     * @param equipmentType
     * @param equipmentManage
     * @return
     */
    public List<ParameterInfo> findByListTypeForGroup(String id, String equipmentType, EquipmentManage equipmentManage) {
        List<ParameterInfo> list = parameterInfoRepository.findListByTypeForMonitor(Integer.valueOf(equipmentType));

        //  实时 这里先定为实时的状态
        List<ParameterInfo> nowList =
                list.stream().filter(parameterInfo -> parameterInfo.getEsAggsMethod().toString().equals("3")).collect(Collectors.toList());
        list.removeAll(nowList);

        //获取电池模组下所有电池单体的code
        List<String> codes = codes(id);

        try {
            // 查询
            nowList = ElasticsearchUtils.getNowGroupValue(codes, nowList, equipmentManage);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        list.addAll(nowList);
        return list;
    }

    /**
     * 电池模组  单体电压
     *
     * @param id
     * @param equipmentManage
     * @return
     */
    public List getVoltage(String id, EquipmentManage equipmentManage, int size) {

        //获取电池模组下所有电池单体的code
        List<String> codes = codes(id);
        //获取项目的IP
        String ip = equipmentManage.getProject().getIp();

        return ElasticsearchUtils.getGroupTopAndBottom(codes, ip, size);
    }

    /**
     * 获取点击电池模组下的所有的电池单体
     *
     * @param id
     * @return
     */
    public List<String> codes(String id) {
        //  电池模组中存在多个电池单体,先获取电池模组下的全部的电池单体
        List<EquipmentManage> equipmentManages = equipmentManageRepository.findByAllBattery(id);
        List<String> codes = new ArrayList<>();
        for (EquipmentManage eqM : equipmentManages) {
            codes.add(eqM.getCode());
        }
        return codes;
    }

    /**
     * 电池模组历史曲线
     *
     * @param id
     * @param objType
     * @param name
     * @param ranges
     * @param freque
     * @param show_type
     * @param start_time
     * @param end_time
     * @return
     */
    public Map groupBatteryHistoryDataEquipment(String id, int objType, String name, String ranges, String freque, String show_type, String start_time, String end_time) {
        // 1. 准备一个返回的结果~
        Map map = new HashMap();
        String title = "";
        // 2. 获取当前设备
        EquipmentManage equipmentManage = equipmentManageRepository.findOne(id);
        ProjectManage projectManage = new ProjectManage();
        // 获取电池模组下的所有的电池单体
        List<EquipmentManage> allBattery = equipmentManageRepository.findByAllBattery(id);
        List<String> codes = new ArrayList<>();
        String macid = allBattery.get(0).getCode().substring(0, allBattery.get(0).getCode().indexOf("#"));
        for (EquipmentManage eq : allBattery) {
            codes.add(eq.getCode().substring(eq.getCode().indexOf("#") + 1, eq.getCode().length()) + "Volt");
        }

        // 3. 获取要查询的字段
        int objName = 3;
        String ip = "";
        if (equipmentManage != null) {
            ip = equipmentManage.getProject().getIp();
        } else {
            projectManage = projectManageRepository.findOne(id);
            ip = projectManage.getIp();
        }
        ParameterInfo parameterInfo = null;
        //获取对应配置的参数测点
        if ("单体电压极值和极差".equals(name)) {
            name = "极值和极差";
            parameterInfo = new ParameterInfo();
            parameterInfo.setName(name);
            parameterInfo.setEsName("Volt");

            show_type = "difference";
        } else {
            parameterInfo = parameterInfoRepository.findOneByNameAndTypeAndObjName(name, objType, objName);
        }
        // 4. 获取时间 这边还没问清这个时间范围到底是怎么样的
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Long startTime = 0L;
        Long endTime = 0L;
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        // 根据时间范围
        List timeRange = getTimeRange(ranges, startTime, endTime, calendar, equipmentManage, title, simpleDateFormat, name, projectManage, start_time, end_time);
        startTime = (Long) timeRange.get(0);
        endTime = (Long) timeRange.get(1);
        title = timeRange.get(2).toString();

        // 5. 先把title放进去
        map.put("title", title);
        // 6. 如果没有找到对应的es_name就直接返回
        if (parameterInfo == null) {
            return map;
        }
        // 7. 判断调用的是什么，然后获取返回值
        JSONObject jsonObject = new JSONObject();
        String esName = parameterInfo.getEsName();
        switch (show_type) {
            case "avg":
                try {
                    jsonObject = unitCellDataScanService.getScanGroupBatteryData(codes,esName, macid, ip, freque, startTime, endTime, "avg");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            case "min":
                try {
                    jsonObject = unitCellDataScanService.getScanGroupBatteryData(codes,esName, macid, ip, freque, startTime, endTime, "min");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            case "max":
                try {
                    jsonObject = unitCellDataScanService.getScanGroupBatteryData(codes,esName, macid, ip, freque, startTime, endTime, "max");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            case "now":
                try {
                    jsonObject = unitCellDataScanService.getScanGroupBatteryData(codes,esName, macid, ip, freque, startTime, endTime, "min");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;

            case "difference":
                try {
                    map = unitCellDataScanService.getGroupBatteryMinAndMax(codes,esName, macid, ip, freque, startTime, endTime, "min");
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                break;
            default:
                return null;
        }
        if ("difference".equals(show_type)) {
            map.put("title", title);
            return map;
        } else {
            map.put("jsonObject", jsonObject);
        }
        // 7. 放进去
        return map;
    }

    /**
     * 时间范围的处理
     * @param ranges
     * @param startTime
     * @param endTime
     * @param calendar
     * @param equipmentManage
     * @param title
     * @param simpleDateFormat
     * @param name
     * @param projectManage
     * @param start_time
     * @param end_time
     * @return
     */
    public List getTimeRange(String ranges ,  Long startTime ,Long endTime , Calendar calendar ,
                             EquipmentManage equipmentManage , String title,
                             SimpleDateFormat simpleDateFormat,String name , ProjectManage projectManage,
    String start_time ,String end_time){
        switch (ranges) {
            case "day":
                startTime = calendar.getTimeInMillis();
                endTime = startTime + 24 * 60 * 60 * 1000 - 1;
                if (equipmentManage != null) {
                    title = equipmentManage.getName() + " " + simpleDateFormat.format(calendar.getTime()) + " " + name;
                } else {
                    title = projectManage.getName() + " " + simpleDateFormat.format(calendar.getTime()) + " " + name;
                }
                break;
            case "week":
                endTime = calendar.getTimeInMillis() + 24 * 60 * 60 * 1000 - 1;
                title = " ~ " + simpleDateFormat.format(calendar.getTime()) + " " + name;
                //calendar.set(Calendar.DAY_OF_WEEK, 1);
                startTime = calendar.getTimeInMillis()- 24 * 60 * 60 * 1000 * 7;
                if (equipmentManage != null) {
                    title = equipmentManage.getName() + " " + simpleDateFormat.format(startTime) + title;
                } else {
                    title = projectManage.getName() + " " + simpleDateFormat.format(startTime) + title;
                }
                break;
            case "month":
                endTime = calendar.getTimeInMillis() + 24 * 60 * 60 * 1000 - 1;
                title = " ~ " + simpleDateFormat.format(calendar.getTime()) + " " + name;
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                startTime = calendar.getTimeInMillis();
                if (equipmentManage != null) {
                    title = equipmentManage.getName() + " " + simpleDateFormat.format(calendar.getTime()) + title;
                } else {
                    title = projectManage.getName() + " " + simpleDateFormat.format(calendar.getTime()) + title;
                }

                break;
            case "year":
                endTime = calendar.getTimeInMillis() + 24 * 60 * 60 * 1000 - 1;
                title = " ~ " + simpleDateFormat.format(calendar.getTime()) + " " + name;
                calendar.set(Calendar.DAY_OF_YEAR, 1);
                startTime = calendar.getTimeInMillis();
                if (equipmentManage != null) {
                    title = equipmentManage.getName() + " " + simpleDateFormat.format(calendar.getTime()) + title;
                } else {
                    title = projectManage.getName() + " " + simpleDateFormat.format(calendar.getTime()) + title;
                }
                break;
            case "custom":
                try {
                    startTime = simpleDateFormat.parse(start_time).getTime();
                    endTime = simpleDateFormat.parse(end_time).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                if (equipmentManage != null) {
                    title = equipmentManage.getName() + " " + start_time + " ~ " + end_time + " " + name;
                } else {
                    title = projectManage.getName() + " " + start_time + " ~ " + end_time + " " + name;
                }
                break;
            default:
                return null;
        }
            List lists = new ArrayList();
            lists.add(startTime);
            lists.add(endTime);
            lists.add(title);
        return lists;
    }
}